package han.sql;

import han.entity.FinanceProjectIdEntity;
import han.entity.FinanceProjectInfoEntity;
import han.entity.InvestCompanyIdEntity;
import han.entity.InvestCompanyInfoEntity;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import static com.han.http.util.Print.printlnInfo;

/**
 * @author: Han
 * @date: 2018/8/8 9:29
 * @dscription: 插入线程
 */
public class InsertThread extends Thread {
    /**
     * 融资项目id插入容器
     */
    private final Set<FinanceProjectIdEntity> INSERT_PROJECT_ID_ENTITY_SET = new HashSet<>();
    /**
     * 融资项目id更新容器
     */
    private final Set<FinanceProjectIdEntity> UPDATE_PROJECT_ID_ENTITY_SET = new HashSet<>();
    /**
     * 融资项目信息插入容器
     */
    private final Set<FinanceProjectInfoEntity> INSERT_PROJECT_INFO_ENTITY_SET = new HashSet<>();
    /**
     * 投资机构id插入容器
     */
    private final Set<InvestCompanyIdEntity> INSERT_ORG_ID_ENTITY_SET = new HashSet<>();
    private final Set<InvestCompanyInfoEntity> INSERT_ORG_INFO_ENTITY_SET = new HashSet<>();
    /**
     * 是否立即执行融资项目id插入
     */
    private boolean insertProIdFlag = false;
    /**
     * 是否立即执行融资项目id更新
     */
    private boolean updateProIdFlag = false;
    /**
     * 是否立即执行融资项目信息插入
     */
    private boolean insertProInfoFlag = false;
    /**
     * 是否立即执行投资机构id插入
     */
    private boolean insertOrgIdFlag = false;
    private boolean insertOrgInfoFlag = false;
    /**
     * 是否继续执行
     */
    private boolean isRunning;

    public InsertThread() {
        this.setName("Thread-数据库操作");
    }

    /**
     * 返回是否有未被操作的数据
     *
     * @return 是否有未被操作的数据
     */
    public boolean hasData() {
        return !INSERT_ORG_ID_ENTITY_SET.isEmpty() || !INSERT_PROJECT_ID_ENTITY_SET.isEmpty() ||
                !INSERT_PROJECT_INFO_ENTITY_SET.isEmpty() || !UPDATE_PROJECT_ID_ENTITY_SET.isEmpty();
    }

    /**
     * 插入容器,以备插入数据库
     *
     * @param idEntityCollection 待插入数据
     */
    public void insertInsertProjectId(Collection<FinanceProjectIdEntity> idEntityCollection) {
        synchronized (INSERT_PROJECT_ID_ENTITY_SET) {
            INSERT_PROJECT_ID_ENTITY_SET.addAll(idEntityCollection);
        }
    }

    /**
     * 立即执行
     */
    public void executeInsertFinanceProIdAtOnce() {
        synchronized (INSERT_PROJECT_ID_ENTITY_SET) {
            if (!INSERT_PROJECT_ID_ENTITY_SET.isEmpty()) {
                printlnInfo(getName() + " 即刻插入融资项目id");
                insertProIdFlag = true;
            }
        }
    }

    /**
     * 插入容器,以备更新数据库
     *
     * @param idEntity 待更新数据
     */
    public void insertUpdateProjectId(FinanceProjectIdEntity idEntity) {
        synchronized (UPDATE_PROJECT_ID_ENTITY_SET) {
            UPDATE_PROJECT_ID_ENTITY_SET.add(idEntity);
        }
    }

    /**
     * 立即执行更新id
     */
    public void executeUpdateFinanceProIdAtOnce() {
        synchronized (UPDATE_PROJECT_ID_ENTITY_SET) {
            if (!UPDATE_PROJECT_ID_ENTITY_SET.isEmpty()) {
                printlnInfo(getName() + " 即刻更新融资项目id");
                updateProIdFlag = true;
            }
        }
    }

    /**
     * 插入容器,以备插入数据库
     *
     * @param infoEntity 待插入数据
     */
    public void insertInsertProjectInfo(FinanceProjectInfoEntity infoEntity) {
        synchronized (INSERT_PROJECT_INFO_ENTITY_SET) {
            INSERT_PROJECT_INFO_ENTITY_SET.add(infoEntity);
        }
    }

    /**
     * 立即执行插入融资项目信息
     */
    public void executeInsertFinanceProInfoAtOnce() {
        synchronized (INSERT_PROJECT_INFO_ENTITY_SET) {
            if (!INSERT_PROJECT_INFO_ENTITY_SET.isEmpty()) {
                printlnInfo(getName() + " 即刻插入融资项目信息");
                insertProInfoFlag = true;
            }
        }
    }

    /**
     * 插入投资机构id
     *
     * @param investCompanyIdEntityCollection 投资机构id
     */
    public void insertInsertOrgId(Collection<InvestCompanyIdEntity> investCompanyIdEntityCollection) {
        synchronized (INSERT_ORG_ID_ENTITY_SET) {
            INSERT_ORG_ID_ENTITY_SET.addAll(investCompanyIdEntityCollection);
        }
    }

    /**
     * 插入投资机构id,准备插入数据库
     */
    public void executeInsertInvestOrgIdAtOnce() {
        synchronized (INSERT_ORG_ID_ENTITY_SET) {
            if (!INSERT_ORG_ID_ENTITY_SET.isEmpty()) {
                printlnInfo(getName() + " 即刻插入投资机构id");
                insertOrgIdFlag = true;
            }
        }
    }

    public void insertInsertOrgInfo(InvestCompanyInfoEntity entity) {
        synchronized (INSERT_ORG_INFO_ENTITY_SET) {
            INSERT_ORG_INFO_ENTITY_SET.add(entity);
        }
    }

    public void executeInsertInvestOrgInfoAtOnce() {
        synchronized (INSERT_ORG_INFO_ENTITY_SET) {
            printlnInfo(getName() + " 即刻插入投资机构信息");
            insertOrgInfoFlag = true;
        }
    }

    @Override
    public void run() {
        printlnInfo(getName() + " 数据库操作线程已启动");
        Operator operator = Operator.getInstance();
        isRunning = true;
        while (isRunning) {
            try {
                //使用同步锁,防止插入数据库的同时,有新的记录插入容器
                synchronized (INSERT_PROJECT_ID_ENTITY_SET) {
                    //是否插入融资项目id
                    boolean isInsertProId = INSERT_PROJECT_ID_ENTITY_SET.size() >= 100 || insertProIdFlag;
                    if (isInsertProId) {
                        //插入
                        operator.insertFinanceProjectId(INSERT_PROJECT_ID_ENTITY_SET);
                        //执行立即插入后,取消立即执行状态
                        insertProIdFlag = false;
                        printlnInfo(getName() + " " + INSERT_PROJECT_ID_ENTITY_SET.size() + "个融资项目id插入完成");
                        //插入完成后清空容器
                        INSERT_PROJECT_ID_ENTITY_SET.clear();
                    }
                }
                //使用同步锁,防止更新数据库的同时,有新的记录插入容器
                synchronized (UPDATE_PROJECT_ID_ENTITY_SET) {
                    //是否更新融资项目id
                    boolean isInsertProId = UPDATE_PROJECT_ID_ENTITY_SET.size() >= 100 || updateProIdFlag;
                    if (isInsertProId) {
                        //更新id
                        operator.updateFinanceProjectId(UPDATE_PROJECT_ID_ENTITY_SET);
                        //执行立即更新后,取消立即执行状态
                        updateProIdFlag = false;
                        printlnInfo(getName() + " " + UPDATE_PROJECT_ID_ENTITY_SET.size() + "个融资项目id更新完成");
                        //更新完成后清空容器
                        UPDATE_PROJECT_ID_ENTITY_SET.clear();
                    }
                }
                //使用同步锁,防止插入数据库的同时,有新的记录插入容器
                synchronized (INSERT_PROJECT_INFO_ENTITY_SET) {
                    //是否插入融资项目id
                    boolean isInsertProId = INSERT_PROJECT_INFO_ENTITY_SET.size() >= 100 || insertProInfoFlag;
                    if (isInsertProId) {
                        //插入
                        operator.insertFinanceProjectInfo(INSERT_PROJECT_INFO_ENTITY_SET);
                        //执行立即插入后,取消立即执行状态
                        insertProInfoFlag = false;
                        printlnInfo(getName() + " " + INSERT_PROJECT_INFO_ENTITY_SET.size() + "个融资项目信息插入完成");
                        //插入完成后清空容器
                        INSERT_PROJECT_INFO_ENTITY_SET.clear();
                    }
                }
                synchronized (INSERT_ORG_ID_ENTITY_SET) {
                    //是否插入投资机构id
                    boolean isInsertOrgId = INSERT_ORG_ID_ENTITY_SET.size() >= 100 || insertOrgIdFlag;
                    if (isInsertOrgId) {
                        //插入
                        operator.insertInvestCompanyId(INSERT_ORG_ID_ENTITY_SET);
                        //执行立即插入后,取消立即执行状态
                        insertOrgIdFlag = false;
                        printlnInfo(getName() + " " + INSERT_ORG_ID_ENTITY_SET.size() + "个投资机构id插入完成");
                        //清理容器
                        INSERT_ORG_ID_ENTITY_SET.clear();
                    }
                }
                synchronized (INSERT_ORG_INFO_ENTITY_SET) {
                    //是否插入投资机构id
                    boolean isInsertOrgId = INSERT_ORG_INFO_ENTITY_SET.size() >= 100 || insertOrgInfoFlag;
                    if (isInsertOrgId) {
                        //插入
                        operator.insertInvestCompanyInfo(INSERT_ORG_INFO_ENTITY_SET);
                        //执行立即插入后,取消立即执行状态
                        insertOrgInfoFlag = false;
                        printlnInfo(getName() + " " + INSERT_ORG_INFO_ENTITY_SET.size() + "个投资机构id插入完成");
                        //清理容器
                        INSERT_ORG_INFO_ENTITY_SET.clear();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    Thread.sleep(1000 * 60);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        printlnInfo(getName() + " " + "数据库插入线程关闭");
    }

    public void close() {
        isRunning = false;
    }
}
